---
---下订单扣库存业务逻辑
---
---
local skuItems, args = KEYS, ARGV
local receive_arg_json = cjson.decode(args[1])

--获取ARGV内的参数并打印
local area = receive_arg_json.areaId
local area2Warehouse = redis.call('zrange', "area:" .. area, 0, -1)

--返回的变量
local result = {}

--判断所有的sku都是否充足的标识: 如果allIsEnough等于传入的sku集合的大小则充足，否则就不充足
local allIsEnough = 0

for i, v in ipairs(skuItems) do
    local orderItem = skuItems[i]
    --redis.log(redis.LOG_DEBUG, skuItems[i])

    --解析订单中每个sku的信息
    local receive_orderItem_json = cjson.decode(orderItem)

    --商品sku id
    local skuId = receive_orderItem_json.goodsSkuId
    --商品购买数量
    local purchaseQuantity = receive_orderItem_json.purchaseQuantity
    --用户此次商品购买的请求时间
    local requestTime = receive_orderItem_json.requestTime
    --此次商品购买的用户ID
    local userAccountId = receive_orderItem_json.userAccountId
    --应发仓库ID
    local shouldWarehouseId = -1
    --实发仓库ID
    local actualWarehouseId = -1

    local skuKey = "GoodsSkuStock::" .. skuId
    local skuExists = redis.call('exists', skuKey)
    if (skuExists == 1) then
        local skuStockAllInfo = redis.call('hgetall', skuKey)

        local skuStockTable = {}
        for j = 1, #skuStockAllInfo, 2 do
            skuStockTable[skuStockAllInfo[j]] = skuStockAllInfo[j + 1]
        end

        --商品实时总库存
        local goodsSkuStorage = skuStockTable["goodsSkuStorage"]
        --商品类型
        local goodsType = skuStockTable["goodsType"]

        local jsonRedisTemp = {}
        jsonRedisTemp["skuId"] = skuId
        jsonRedisTemp["goodsType"] = tonumber(goodsType)
        jsonRedisTemp["requestTime"] = requestTime
        jsonRedisTemp["userAccountId"] = userAccountId

        if purchaseQuantity ~= nil and goodsSkuStorage ~= nil then
            -- 首先判断总库存是否充足,如果总库存充足则需要查看每个仓库的库存是否充足
            if (tonumber(purchaseQuantity) <= tonumber(goodsSkuStorage)) then
                --是否是预售 :1 是,0 否
                jsonRedisTemp["isPre"] = 0
                jsonRedisTemp["purchaseQuantity"] = tonumber(purchaseQuantity)
                jsonRedisTemp["allEnough"] = 1

                if (goodsType == tostring(2)) then
                    --第三方商品
                    jsonRedisTemp["isEnough"] = 1
                    jsonRedisTemp["shouldWarehouseId"] = shouldWarehouseId
                    jsonRedisTemp["actualWarehouseId"] = actualWarehouseId
                    jsonRedisTemp["goodsSkuStorage"] = tonumber(goodsSkuStorage)

                    allIsEnough = allIsEnough + 1
                else
                    --自营商品
                    --循环依次判断哪个仓库的库存充足,怎么作为实际库存发货仓库
                    for index, warehouseId in ipairs(area2Warehouse) do
                        local skuWarehouseKey = "GoodsSkuWareStock::" .. skuId .. ":" .. warehouseId
                        --对应分仓的实时库存
                        local saleStockQuantity = redis.call('hget', skuWarehouseKey, "saleStockQuantity")

                        if (saleStockQuantity) then
                            if (shouldWarehouseId == -1) then
                                shouldWarehouseId = tonumber(warehouseId)
                            end

                            if (tonumber(purchaseQuantity) <= tonumber(saleStockQuantity)) then
                                actualWarehouseId = tonumber(warehouseId);
                                jsonRedisTemp["goodsSkuStorage"] = tonumber(saleStockQuantity)
                                break ;
                            end
                        end
                    end

                    jsonRedisTemp["shouldWarehouseId"] = shouldWarehouseId
                    jsonRedisTemp["actualWarehouseId"] = actualWarehouseId

                    if (shouldWarehouseId == -1 and actualWarehouseId == -1) then
                        jsonRedisTemp["isEnough"] = 0
                    end

                    if (shouldWarehouseId ~= -1 and actualWarehouseId == -1) then
                        jsonRedisTemp["isEnough"] = 0
                    end

                    if (shouldWarehouseId ~= -1 and actualWarehouseId ~= -1) then
                        jsonRedisTemp["isEnough"] = 1
                        allIsEnough = allIsEnough + 1
                    end
                end
            else
                --总库存不足,则查看预售库存是否充足
                local preStorage = skuStockTable["preStorage"]
                if (tonumber(purchaseQuantity) <= tonumber(preStorage)) then
                    --预售充足
                    jsonRedisTemp["isEnough"] = 1
                    jsonRedisTemp["isPre"] = 1
                    jsonRedisTemp["shouldWarehouseId"] = shouldWarehouseId
                    jsonRedisTemp["actualWarehouseId"] = actualWarehouseId
                    jsonRedisTemp["purchaseQuantity"] = purchaseQuantity
                    jsonRedisTemp["preStorage"] = preStorage

                    allIsEnough = allIsEnough + 1
                else
                    --预售不足
                    jsonRedisTemp["isEnough"] = 0
                    jsonRedisTemp["shouldWarehouseId"] = shouldWarehouseId
                    jsonRedisTemp["actualWarehouseId"] = actualWarehouseId

                    if (goodsType == "2") then
                        --第三方商品
                        jsonRedisTemp["isPre"] = 0
                    else
                        --自营商品
                        jsonRedisTemp["isPre"] = 1
                    end
                end
            end
            --springboot redistemplate接收的是List,如果返回的数组内容是json对象,需要将json对象转成字符串,客户端才能接收
            result[i] = cjson.encode(jsonRedisTemp)
        end
    else
        result = nil
        return result
    end
end

--如果一次请求的所有sku都充足则扣库存
if (allIsEnough == #skuItems) then
    for i, v in ipairs(result) do
        local skuStock = cjson.decode(v)

        local skuId = skuStock["skuId"]
        local goodsType = skuStock["goodsType"]
        local purchaseQuantity = skuStock["purchaseQuantity"]
        local skuKey = "GoodsSkuStock::" .. skuId

        local isPre = skuStock["isPre"]
        if (tonumber(isPre) == 1) then
            redis.call('hincrby', skuKey, "preStorage", -purchaseQuantity)
            redis.call('hincrby', skuKey, "lockedStorage", purchaseQuantity)
        else
            redis.call('hincrby', skuKey, "goodsSkuStorage", -purchaseQuantity)
            redis.call('hincrby', skuKey, "lockedStorage", purchaseQuantity)

            if (goodsType ~= "2") then
                local actualWarehouseId = skuStock["actualWarehouseId"]
                local skuWarehouseKey = "GoodsSkuWareStock::" .. skuId .. ":" .. actualWarehouseId
                redis.call('hincrby', skuWarehouseKey, "saleStockQuantity", -purchaseQuantity)
                redis.call('hincrby', skuWarehouseKey, "lockedStockQuantity", purchaseQuantity)
            end
        end

        local logId = redis.call('incr', "Stock::ID")
        redis.call('set', "Stock::Log::" .. logId, v)
        skuStock["lockedStockId"] = logId
        result[i] = cjson.encode(skuStock)
    end
end

redis.log(redis.LOG_DEBUG, cjson.encode(result)) --打印返回的数组结果，这里返回需要以字符返回
return result
